package com.hosever.core;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.Collection;
import java.util.List;
import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.hosever.core.model.OrderBy;
import com.hosever.core.model.Page;
import com.hosever.core.model.PageRequest;
import com.hosever.utils.OrderByUtils;

@Repository
public abstract class AbstractDaoImpl<E, ID extends Serializable> implements
		AbstractDao<E> {
	/*
	 * @Autowired protected HibernateTemplate hibernateTemplate;
	 */
	@Autowired
	protected SessionFactory sessionFactory;
	private String systemName = "hosever";
	private static Logger logger = Logger.getLogger(AbstractDaoImpl.class);
	private Class<E> entityClass = null;
	private String className = "";
	public Session getCurrentSession() {
		return sessionFactory.getCurrentSession();// 增删改使用的session
	}
	public Session openSession() {
		return sessionFactory.openSession();// 查询使用的session
	}
	@SuppressWarnings("unchecked")
	public AbstractDaoImpl() {
		entityClass = (Class<E>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
		className = entityClass.getName();
	}
	@SuppressWarnings("unchecked")
	public List<E> list() {
		OrderBy orderBy = new OrderBy("createDate",
				OrderByUtils.ORDER_TYPE_DESC);
		String hql = "from " + className + orderBy.getOrderSQL();
		logger.debug(systemName + "-Debug:查询列表" + className);
		Query query = this.openSession().createQuery(hql);
		return (List<E>) query.list();
	}
	@SuppressWarnings("unchecked")
	public Page<E> page(PageRequest pageRequest) {
		if (pageRequest == null) {
			return null;
		}
		OrderBy orderBy = new OrderBy("createDate",
				OrderByUtils.ORDER_TYPE_DESC);
		final String hql = "from " + className + orderBy.getOrderSQL();
		logger.debug(systemName + "-Debug:分页查询" + className);
		List<E> result = getListForPage(hql, pageRequest.getStart(),
				pageRequest.getPageSize());
		String countHql = "select count(*)  from " + className
				+ orderBy.getOrderSQL();
		Query query = this.openSession().createQuery(countHql);
		List<Object> countResult = query.list();
		int count = 0;
		if (!countResult.isEmpty()) {
			count = Integer.valueOf(String.valueOf(countResult.get(0)));
		}
		logger.debug(systemName + "-Debug:分页总条数" + count);
		Page<E> page = setPageInfo(pageRequest, result);
		page.setTotalSize(count);
		return page;
	}
	/**
	 * 使用hql 语句进行操作
	 * 
	 * @param hql
	 * @param offset
	 * @param length
	 * @return List
	 */
	@SuppressWarnings({ "unchecked" })
	public List<E> getListForPage(final String hql, final int offset,
			final int length) {
		/*List<E> list = (List<E>) hibernateTemplate
				.executeFind(new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query query = session.createQuery(hql);
						query.setFirstResult(offset);
						query.setMaxResults(length);
						List<E> list = query.list();
						return list;
					}
				});*/
		Query query = this.openSession().createQuery(hql);
		query.setFirstResult(offset);
		query.setMaxResults(length);
		List<E> list = query.list();
		return list;
	}
	private Page<E> setPageInfo(PageRequest pageRequest, List<E> content) {
		Page<E> page = new Page<E>();
		page.setContent(content);
		page.setCurrentPage(pageRequest.getCurrentPage());
		page.setPageSize(pageRequest.getPageSize());
		page.setTotalPage(pageRequest.getTotalPage());
		page.setTotalSize(pageRequest.getTotalSize());
		return page;
	}
	@SuppressWarnings({ "unchecked" })
	public E findById(String id) {
		String hql = "from " + className + " e where e.id = :id";
		logger.debug(systemName + "-Debug:查找" + className + " id:" + id);
		
		Query query = this.openSession().createQuery(hql);
		query.setParameter("id", id);
		List<E> list = query.list();
		if(list==null || list.isEmpty()){
			return null;
		}
		return (E) query.list().get(0);
	}
	@SuppressWarnings("unchecked")
	public List<E> findByIds(Collection<String> ids) {
		String hql = "from " + className + " e where e.id in (:ids)";
		Query query = this.openSession().createQuery(hql);
		query.setParameter("ids", ids);
		List<E> list = query.list();
		return list;
	}
	public boolean save(E e) {
		if (e == null) {
			return false;
		}
		this.getCurrentSession().saveOrUpdate(e);
		logger.debug(systemName + "-Debug:保存" + e);
		return true;
	}
	public boolean update(E e) {
		if (e == null) {
			return false;
		}
		this.getCurrentSession().saveOrUpdate(e);
		logger.debug(systemName + "-Debug:更新" + e);
		return true;
	}
	public boolean del(E e) {
		if (e == null) {
			return false;
		}
		this.getCurrentSession().delete(e);
		logger.debug(systemName + "-Debug:物理删除" + e);
		return true;
	}
	// @SuppressWarnings("unchecked")
	// public List<E> getListForPage(final String hql, final int offset, final
	// int length){
	// List<E> list = (List<E>)this.hibernateTemplate.executeFind(new
	// HibernateCallback(){
	// public Object doInHibernate(Session session) throws HibernateException,
	// SQLException {
	// Query query = session.createQuery(hql);
	// query.setFirstResult(offset);
	// query.setMaxResults(length);
	// List list = query.list();
	// return list;
	// }
	// });
	// return list;
	// }
	@SuppressWarnings({ "unchecked", "null" })
	public E customQuerySingle(String hql) {
		Query query = this.openSession().createQuery(hql);
		List<E> objects = query.list();
		logger.debug(systemName + "-Debug:查找单个" + className);
		if(objects!=null || objects.isEmpty()){
			return null;
		}
		return objects.get(0);
	}
	@SuppressWarnings("unchecked")
	public List<E> customQuery(String hql) {
		logger.debug(systemName + "-Debug:查找多个" + className);
		Query query = this.openSession().createQuery(hql);
		List<E> list = query.list();
		return list;
	}
}
